package com.farm.controller;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.farm.entity.Product;
import com.farm.entity.User;
import com.farm.service.ProductService;

@Controller
public class ProductController {

    @Autowired
    private ProductService productService;

    @GetMapping("/")
    public String home(@RequestParam(required = false) String keyword, Model model) {
        List<Product> products;
        if (keyword != null && !keyword.trim().isEmpty()) {
            products = productService.searchProducts(keyword, null, true);
        } else {
            products = productService.findApprovedProducts();
        }
        model.addAttribute("products", products);
        return "home";
    }

    @GetMapping("/products/category/{category}")
    public String productsByCategory(@PathVariable String category, Model model) {
        List<Product> products = productService.findByCategory(category);
        model.addAttribute("products", products);
        model.addAttribute("category", category);
        return "products";
    }

    @GetMapping("/products/{id}")
    public String productDetail(@PathVariable Long id, Model model) {
        Product product = productService.findById(id);
        model.addAttribute("product", product);
        return "product-detail";
    }

    // Farmer endpoints
    @GetMapping("/farmer/products")
    public String farmerProducts(@AuthenticationPrincipal User user, Model model) {
        List<Product> products = productService.findByFarmer(user);
        model.addAttribute("products", products);
        return "farmer/products";
    }

    @GetMapping("/farmer/products/new")
    public String newProductForm(Model model) {
        model.addAttribute("product", new Product());
        return "farmer/product-form";
    }

    @PostMapping("/farmer/products")
    public String createProduct(@AuthenticationPrincipal User user,
                              @ModelAttribute Product product,
                              @RequestParam("imageFile") MultipartFile imageFile) throws IOException {
        if (!imageFile.isEmpty()) {
            String fileName = UUID.randomUUID().toString() + "_" + imageFile.getOriginalFilename();
            Path uploadPath = Paths.get("uploads");
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }
            Files.copy(imageFile.getInputStream(), uploadPath.resolve(fileName));
            product.setImage("/uploads/" + fileName);
        }
        product.setFarmer(user);
        productService.createProduct(product);
        return "redirect:/farmer/products";
    }

    @GetMapping("/farmer/products/{id}/edit")
    public String editProductForm(@PathVariable Long id, Model model) {
        Product product = productService.findById(id);
        model.addAttribute("product", product);
        return "farmer/product-form";
    }

    @PostMapping("/farmer/products/{id}")
    public String updateProduct(@PathVariable Long id,
                              @ModelAttribute Product product,
                              @RequestParam(value = "imageFile", required = false) MultipartFile imageFile) throws IOException {
        if (imageFile != null && !imageFile.isEmpty()) {
            String fileName = UUID.randomUUID().toString() + "_" + imageFile.getOriginalFilename();
            Path uploadPath = Paths.get("uploads");
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }
            Files.copy(imageFile.getInputStream(), uploadPath.resolve(fileName));
            product.setImage("/uploads/" + fileName);
        }
        productService.updateProduct(product);
        return "redirect:/farmer/products";
    }

    @PostMapping("/farmer/products/{id}/delete")
    public String deleteFarmerProduct(@PathVariable Long id) {
        productService.deleteProduct(id);
        return "redirect:/farmer/products";
    }

    // Admin endpoints
    @GetMapping("/admin/products")
    public String adminProducts(
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String category,
            @RequestParam(required = false) String status,
            Model model) {
        List<Product> products;
        if (keyword != null || category != null || status != null) {
            Boolean approved = null;
            if ("approved".equals(status)) {
                approved = true;
            } else if ("pending".equals(status)) {
                approved = false;
            }
            products = productService.searchProducts(keyword, category, approved);
        } else {
            products = productService.findAllProducts();
        }
        model.addAttribute("products", products);
        return "admin/products";
    }

    @GetMapping("/admin/products/pending")
    public String pendingProducts(Model model) {
        List<Product> products = productService.findPendingProducts();
        model.addAttribute("products", products);
        return "admin/pending-products";
    }

    @PostMapping("/admin/products/{id}/approve")
    @ResponseBody
    public String approveProduct(@PathVariable Long id) {
        try {
            productService.approveProduct(id);
            return "success";
        } catch (RuntimeException e) {
            return "error: " + e.getMessage();
        }
    }

    @PostMapping("/admin/products/{id}")
    @ResponseBody
    public ResponseEntity<String> deleteProduct(@PathVariable Long id) {
        try {
            productService.deleteProduct(id);
            return ResponseEntity.ok("success");
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("error: " + e.getMessage());
        }
    }

    @GetMapping("/admin/products/export")
    public void exportProducts(HttpServletResponse response) throws IOException {
        response.setContentType("text/csv");
        response.setHeader("Content-Disposition", "attachment; filename=\"products.csv\"");
        
        List<Product> products = productService.findAllProducts();
        
        try (CSVPrinter csvPrinter = new CSVPrinter(response.getWriter(), CSVFormat.DEFAULT
                .withHeader("ID", "名称", "类别", "价格", "库存", "状态", "农户"))) {
            for (Product product : products) {
                csvPrinter.printRecord(
                    product.getId(),
                    product.getName(),
                    product.getCategory(),
                    product.getPrice(),
                    product.getStock(),
                    product.isApproved() ? "已审核" : "待审核",
                    product.getFarmer().getRealName()
                );
            }
        }
    }

    @GetMapping("/admin/products/{id}")
    @ResponseBody
    public ResponseEntity<?> getProduct(@PathVariable Long id) {
        try {
            Product product = productService.findById(id);
            if (product == null) {
                return ResponseEntity.notFound().build();
            }
            return ResponseEntity.ok(product);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("error: " + e.getMessage());
        }
    }

    @PostMapping("/admin/products/update")
    @ResponseBody
    public String updateProduct(@RequestParam Long id,
                              @RequestParam String name,
                              @RequestParam String description,
                              @RequestParam String category,
                              @RequestParam BigDecimal price,
                              @RequestParam Integer stock,
                              @RequestParam(required = false) MultipartFile imageFile) {
        try {
            Product product = productService.findById(id);
            product.setName(name);
            product.setDescription(description);
            product.setCategory(category);
            product.setPrice(price);
            product.setStock(stock);

            if (imageFile != null && !imageFile.isEmpty()) {
                String imagePath = saveImage(imageFile);
                product.setImage(imagePath);
            }

            productService.updateProduct(product);
            return "success";
        } catch (Exception e) {
            return "error: " + e.getMessage();
        }
    }

    private String saveImage(MultipartFile file) throws IOException {
        String uploadDir = "uploads/products";
        Path uploadPath = Paths.get(uploadDir);
        if (!Files.exists(uploadPath)) {
            Files.createDirectories(uploadPath);
        }

        String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
        Path filePath = uploadPath.resolve(fileName);
        Files.copy(file.getInputStream(), filePath);

        return uploadDir + "/" + fileName;
    }
} 